package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huiminpay.common.cache.Cache;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.util.RedisUtil;
import com.huiminpay.paymentagent.api.conf.AliConfigParam;
import com.huiminpay.paymentagent.api.dto.PaymentResponseDTO;
import com.huiminpay.paymentagent.api.dto.TradeStatus;
import com.huiminpay.paymentagent.constant.AliCodeConstants;
import com.huiminpay.transaction.api.PayChannelService;
import com.huiminpay.transaction.api.dto.PayChannelDTO;
import com.huiminpay.transaction.api.dto.PayChannelParamDTO;
import com.huiminpay.transaction.api.dto.PlatformChannelDTO;
import com.huiminpay.transaction.convert.PayChannelParamConvert;
import com.huiminpay.transaction.convert.PlatformChannelConvert;
import com.huiminpay.transaction.entity.AppPlatformChannel;
import com.huiminpay.transaction.entity.PayChannelParam;
import com.huiminpay.transaction.entity.PlatformChannel;
import com.huiminpay.transaction.mapper.AppPlatformChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelParamMapper;
import com.huiminpay.transaction.mapper.PlatformChannelMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;


@Slf4j
@Service
public class PayChannelServiceImpl implements PayChannelService {

    @Autowired
    private PlatformChannelMapper platformChannelMapper;
    @Autowired
    private AppPlatformChannelMapper appPlatformChannelMapper;
    @Autowired
    private PayChannelParamMapper payChannelParamMapper;
    @Resource
    private Cache cache;

    @Override
    public List<PlatformChannelDTO> queryPlatformChannel() {
        List<PlatformChannel> platformChannels = platformChannelMapper.selectList(null);
        List<PlatformChannelDTO> platformChannelDTOS = PlatformChannelConvert.INSTANCE.listentity2listdto(platformChannels);
        return platformChannelDTOS;
    }

    @Transactional
    @Override
    public void bindPlatformChannelForApp(String appId, String platformChannelCodes) throws BusinessException {
        //根据appid和平台服务类型code查询app_platform_channel
        LambdaQueryWrapper<AppPlatformChannel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(!StringUtils.isEmpty(appId), AppPlatformChannel::getAppId, appId).eq(!StringUtils.isEmpty(platformChannelCodes), AppPlatformChannel::getPlatformChannel, platformChannelCodes);

        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(queryWrapper);
        //如若没有，则进行绑定
        if (ObjectUtils.isEmpty(appPlatformChannel)) {
            appPlatformChannel = new AppPlatformChannel();
            appPlatformChannel.setAppId(appId);
            appPlatformChannel.setPlatformChannel(platformChannelCodes);
            appPlatformChannelMapper.insert(appPlatformChannel);
        }
    }

    @Override
    public int queryAppBindPlatformChannel(String appId, String platformChannelCodes) throws BusinessException {
        LambdaQueryWrapper<AppPlatformChannel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(!StringUtils.isEmpty(appId), AppPlatformChannel::getAppId, appId).eq(!StringUtils.isEmpty(platformChannelCodes), AppPlatformChannel::getPlatformChannel, platformChannelCodes);
        Integer count = appPlatformChannelMapper.selectCount(queryWrapper);
        return count > 0 ? 1 : 0;
    }

    @Override
    public List<PayChannelDTO> queryPayChannelByPlatformChannel(String platformChannelCode) throws BusinessException {

        return platformChannelMapper.selectPayChannelByPlatformChannel(platformChannelCode);
    }

    /**
     * 5.4.4 交易服务-支付渠道参数配置接口(接口⑦)
     * 保存支付渠道参数
     *
     * @param dto 支付渠道参数
     * @throws BusinessException
     */
    @Override
    public void savePayChannelParam(PayChannelParamDTO dto) throws BusinessException {
        if (ObjectUtils.isEmpty(dto) || StringUtils.isBlank(dto.getPayChannel()) || StringUtils.isBlank(dto.getAppId()) || StringUtils.isBlank(dto.getPlatformChannelCode())) {
            throw new BusinessException(CommonErrorCode.E_100108);
        }
        //根据appid和服务类型查询应用与服务类型绑定id
        Long appPlatformChannelId = selectIdByAppPlatformChannel(dto.getAppId(), dto.getPlatformChannelCode());
        //根据应用与服务类型绑定id和支付渠道查询参数信息
        LambdaQueryWrapper<PayChannelParam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId).eq(!StringUtils.isBlank(dto.getPayChannel()), PayChannelParam::getPayChannel, dto.getPayChannel());
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(wrapper);

        if (ObjectUtils.isEmpty(payChannelParam)) {
            //添加新配置
            PayChannelParam entity = PayChannelParamConvert.INSTANCE.dto2entity(dto);
            entity.setId(null);
            entity.setAppPlatformChannelId(appPlatformChannelId);
            payChannelParamMapper.insert(entity);
        } else {
            payChannelParam.setParam(dto.getParam());
            payChannelParam.setChannelName(dto.getChannelName());
            payChannelParam.setPayChannel(dto.getPayChannel());
            payChannelParamMapper.updateById(payChannelParam);
        }
        updateCache(dto.getAppId(), dto.getPlatformChannelCode());
    }

    /**
     * 根据应用id 、服务类型 code 查询应用与服务类型的绑定id
     *
     * @param appId
     * @param platformChannelCode
     * @return
     */
    private Long selectIdByAppPlatformChannel(String appId, String platformChannelCode) {
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(new LambdaQueryWrapper<AppPlatformChannel>().eq(AppPlatformChannel::getAppId, appId).eq(AppPlatformChannel::getPlatformChannel, platformChannelCode));
        if (appPlatformChannel != null) {
            return appPlatformChannel.getId();//应用与服务类型的绑定id
        }
        return null;
    }

    @Override
    public List<PayChannelParamDTO> queryPayChannelParamByAppAndPlatform(String appId, String platformChannel) throws BusinessException {

        if (StringUtils.isBlank(appId) || StringUtils.isBlank(platformChannel)) {
            throw new BusinessException(CommonErrorCode.UNKNOWN);
        }

        //先从redis查询，如果有则返回
        //从缓存查询
        //1.key的构建 如：HM_PAY_PARAM:b910da455bc84514b324656e1088320b:huimin_c2b
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
        //是否有缓存
        Boolean exists = cache.exists(redisKey);
        if (exists) {
            //从redis获取支付渠道参数列表（json串）
            String PayChannelParamDTO_String = cache.get(redisKey);
            //将json串转成 List<PayChannelParamDTO>
            List<PayChannelParamDTO> payChannelParamDTOS = JSON.parseArray(PayChannelParamDTO_String, PayChannelParamDTO.class);
            return payChannelParamDTOS;
        }


        Long appPlatformChannelId = selectIdByAppPlatformChannel(appId, platformChannel);
        LambdaQueryWrapper<PayChannelParam> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId);
        List<PayChannelParam> paramList = payChannelParamMapper.selectList(queryWrapper);

        List<PayChannelParamDTO> payChannelParamDTOS = PayChannelParamConvert.INSTANCE.listentity2listdto(paramList);
        cache.set(redisKey, JSON.toJSONString(payChannelParamDTOS));
        return payChannelParamDTOS;
    }

    @Override
    public PayChannelParamDTO queryParamByAppPlatformAndPayChannel(String appId, String platformChannel, String payChannel) throws BusinessException {
        List<PayChannelParamDTO> payChannelParamDTOS = queryPayChannelParamByAppAndPlatform(appId, platformChannel);
        for (PayChannelParamDTO payChannelParam : payChannelParamDTOS) {
            if (payChannelParam.getPayChannel().equals(payChannel)) {
                return payChannelParam;
            }
        }
        return null;

    }


    private void updateCache(String appId, String platformChannel) {
        //处理redis缓存
        //1.key的构建 如：HM_PAY_PARAM:b910da455bc84514b324656e1088320b:huimin_c2b
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
        //2.查询redis,检查key是否存在
        Boolean exists = cache.exists(redisKey);
        if (exists) {//存在，则清除
            //删除原有缓存
            cache.del(redisKey);
        }
        //3.从数据库查询应用的服务类型对应的实际支付参数，并重新存入缓存
        List<PayChannelParamDTO> paramDTOS = queryPayChannelParamByAppAndPlatform(appId, platformChannel);
        if (paramDTOS != null) {
            //存入缓存
            cache.set(redisKey, JSON.toJSON(paramDTOS).toString());
        }
    }



}